package com.gk.panda.apis.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dahuatech.icc.exception.ClientException;
import com.dahuatech.icc.oauth.http.DefaultClient;
import com.dahuatech.icc.oauth.http.IClient;
import com.gk.panda.apis.config.IccConfig;
import com.gk.panda.apis.entity.DataVisualization.bo.BiodiversityCountByTypeBo;
import com.gk.panda.apis.entity.DataVisualization.bo.PatrolIncidentsCountBo;
import com.gk.panda.apis.entity.DataVisualization.vo.*;
import com.gk.panda.apis.entity.targetedSms.dto.SmsCountDto;
import com.gk.panda.apis.enums.BiodiversityEnum;
import com.gk.panda.apis.mapper.DataVisualizationMapper;
import com.gk.panda.apis.service.*;
import com.gk.panda.commons.constant.Constants;
import com.gk.panda.commons.exception.ServerException;
import com.gk.panda.pojo.RealtimeShoot;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName: DataVisualizationServiceImpl
 * @Description: 数据可视化
 * @author: Sir.yang
 * @date: 2022/11/9 11:41
 * @version: 1.0
 **/
@Service
@Slf4j
public class DataVisualizationServiceImpl implements DataVisualizationService {

    @Autowired
    private TargetedSmsService targetedSmsService;

    @Autowired
    private DeviceManagerService deviceManagerService;

    @Autowired
    private DeviceHandheldTerminalService handheldTerminalService;

    @Autowired
    private TransectManagerService transectManagerService;

    @Autowired
    private DataVisualizationMapper dataVisualizationMapper;

    @Autowired
    private ElecRailService elecRailService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private RealtimeShootService realtimeShootService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IccConfig iccConfig;

    /**
     * @description: 获取靶向短信登录地址
     * @param: []
     * @return: java.lang.String
     * @date: 2022/11/9 11:44
     * @version: 1.0
     **/
    @Override
    public String getSmsLoginUrl() {
        return targetedSmsService.getLoginUrl();
    }

    /**
     * @description: 获取靶向短信统计数据
     * @param: []
     * @return: com.gk.panda.apis.entity.DataVisualization.vo.TargetedSmsDataVo
     * @date: 2022/11/9 11:50
     * @version: 1.0
     **/
    @Override
    public TargetedSmsDataVo getTargetedSmsData() {
        String url = "https://ryd.189store.com/yktsms/xiongmao/sendRes";
        String result = restTemplate.getForObject(url, String.class);
        SmsCountDto smsCountDto = JSONObject.parseObject(result, SmsCountDto.class);
        if (!smsCountDto.getCode().equals(Constants.SUCCESS)) {
            throw new ServerException("调用靶向短信接口失败!");
        }
        Map<String, Integer> data = smsCountDto.getData();
        TargetedSmsDataVo dataVo = new TargetedSmsDataVo();
        dataVo.setNumOfCoreAreas(data.get("centerCount"));
        dataVo.setNumOfGeneralAreas(data.get("normalCount"));
        dataVo.setTotalNum(data.get("totalCount"));
        return dataVo;

//        //TODO 待靶向短信那边提供真实的连接数据，和能分辨的IDS
//        TargetedSmsDataVo vo = new TargetedSmsDataVo();
//        //获取一般区域数据
//        List<TargetedSmsVo> numOfGeneralAreasList = targetedSmsService.getetTargetedSmsData("2022-10-01", "2022-11-03", 6);
//        //获取核心区域数据
//        List<TargetedSmsVo> numOfCoreAreasList = targetedSmsService.getetTargetedSmsData("2022-10-01", "2022-11-03", 6);
//        if(!CollectionUtils.isEmpty(numOfGeneralAreasList)){
//            numOfGeneralAreasList.forEach(msg ->{
//                //统计实际完成数量
//                Integer total = msg.getCmccCnt() + msg.getUnicomCnt() + msg.getTelCnt();
//                if(null == vo.getNumOfGeneralAreas()){
//                    vo.setNumOfGeneralAreas(total);
//                }else{
//                    vo.setNumOfGeneralAreas(total + vo.getNumOfGeneralAreas());
//                }
//            });
//        }
//        if(!CollectionUtils.isEmpty(numOfCoreAreasList)){
//            for (TargetedSmsVo smsVo : numOfCoreAreasList) {
//                Integer total = smsVo.getCmccCnt() + smsVo.getUnicomCnt() + smsVo.getTelCnt();
//                if(null == vo.getNumOfCoreAreas()){
//                    vo.setNumOfCoreAreas(total);
//                    continue;
//                }
//                vo.setNumOfCoreAreas(total + vo.getNumOfCoreAreas());
//            }
//        }
//        vo.setTotalNum(vo.getNumOfCoreAreas() + vo.getNumOfGeneralAreas());
//        return vo;
    }

    /**
     * @description: 区域热力人数数据统计
     * @param: []
     * @return:
     * @date: 2022/11/11 14:18
     * @version: 1.0
     **/
    @Override
    public Map<String, Object> getElectronicFenceCount() throws Exception {
        return elecRailService.getRegionalPersonCount();
    }

    /**
     * @param orgId
     * @description: 监控设备数据统计
     * @param: []
     * @return: com.gk.panda.apis.entity.DataVisualization.vo.MonitoringEquipmentVo
     * @date: 2022/11/11 14:18
     * @version: 1.0
     */
    @Override
    public MonitoringEquipmentVo getMonitoringEquipmentCount(String orgId) {
        List<Integer> orgIds = getOrgIds(orgId);
        //获取红外相相机和摄像机数量
        MonitoringEquipmentVo vo = deviceManagerService.getMonitoringEquipmentCount(orgIds);
        //获取手持终端数量
        Integer handheldTerminalNum = handheldTerminalService.getHandheldTerminaCountByOrgId(orgIds);
        vo.setHandheldTerminalNum(handheldTerminalNum);
        int total = (null == vo.getCameraNum() ? Constants.ZERO : vo.getCameraNum())
                + (null == vo.getVideoCameraNum() ? Constants.ZERO : vo.getVideoCameraNum())
                + (null == vo.getHandheldTerminalNum() ? Constants.ZERO : vo.getHandheldTerminalNum());
        vo.setTotalNum(total);
        return vo;
    }

    /**
     * @param orgId
     * @description: 巡护样线数据统计
     * @param: []
     * @return: java.lang.Integer
     * @date: 2022/11/11 14:19
     * @version: 1.0
     */
    @Override
    public Integer getTransectCount(String orgId) {
        List<Integer> orgIds = getOrgIds(orgId);
        return transectManagerService.getCountByOrgId(orgIds);
    }

    /**
     * @param orgId
     * @description: 生物多样性数据统计
     * @param: []
     * @return: com.gk.panda.apis.entity.DataVisualization.vo.BiodiversityCountVo
     * @date: 2022/11/11 14:19
     * @version: 1.0
     */
    @Override
    public BiodiversityCountVo getBiodiversityCount(String orgId) {
        BiodiversityCountVo vo = new BiodiversityCountVo();
        List<Integer> puisneOrgIds = getOrgIds(orgId);
        //0-动物 1-植物
        Integer animalTotal = Constants.ZERO;
        Integer botanyTotal = Constants.ZERO;
        List<BiodiversityCountByTypeVo> vos = new ArrayList<>();
        animalTotal = dataVisualizationMapper.getBioCountByOrgId(puisneOrgIds, 0);
        botanyTotal = dataVisualizationMapper.getBioCountByOrgId(puisneOrgIds, 1);
        BiodiversityCountByTypeVo kingdom = new BiodiversityCountByTypeVo();
        kingdom.setBiodiversityType("界");
        kingdom.setAnimalTotal(animalTotal > 0 ? 1 : 0);
        kingdom.setBotanyTotal(botanyTotal > 0 ? 1 : 0);
        vos.add(kingdom);
        //统计门类型数量
        List<BiodiversityCountByTypeBo> phylums = dataVisualizationMapper.getCountByOrgId(puisneOrgIds, BiodiversityEnum.PHYLUM.getCode());
        putBiodiversityCountByType(BiodiversityEnum.PHYLUM.getDesc(), phylums, vos, animalTotal, botanyTotal);
        //统计纲类型数量
        List<BiodiversityCountByTypeBo> klasses = dataVisualizationMapper.getCountByOrgId(puisneOrgIds, BiodiversityEnum.KLASSE.getCode());
        putBiodiversityCountByType(BiodiversityEnum.KLASSE.getDesc(), klasses, vos, animalTotal, botanyTotal);
        //统计目类型数量
        List<BiodiversityCountByTypeBo> ordos = dataVisualizationMapper.getCountByOrgId(puisneOrgIds, BiodiversityEnum.ORDO.getCode());
        putBiodiversityCountByType(BiodiversityEnum.ORDO.getDesc(), ordos, vos, animalTotal, botanyTotal);
        //统计科类型数量
        List<BiodiversityCountByTypeBo> familys = dataVisualizationMapper.getCountByOrgId(puisneOrgIds, BiodiversityEnum.FAMILY.getCode());
        putBiodiversityCountByType(BiodiversityEnum.FAMILY.getDesc(), familys, vos, animalTotal, botanyTotal);
        //统计属类型数量
        List<BiodiversityCountByTypeBo> genus = dataVisualizationMapper.getCountByOrgId(puisneOrgIds, BiodiversityEnum.GENUS.getCode());
        putBiodiversityCountByType(BiodiversityEnum.GENUS.getDesc(), genus, vos, animalTotal, botanyTotal);
        //统计种类型数量
        List<BiodiversityCountByTypeBo> species = dataVisualizationMapper.getCountByOrgId(puisneOrgIds, BiodiversityEnum.SPECIES.getCode());
        putBiodiversityCountByType(BiodiversityEnum.SPECIES.getDesc(), species, vos, animalTotal, botanyTotal);
        vo.setCountNumByType(vos);
        vo.setAnimalTotal(animalTotal);
        vo.setBotanyTotal(botanyTotal);
        return vo;
    }

    /**
     * @description: 整合统计值
     * @param: [biodiversityType, bos, list, animalTotal, botanyTotal]
     * @return: void
     * @date: 2022/11/11 18:40
     * @version: 1.0
     **/
    private void putBiodiversityCountByType(String biodiversityType, List<BiodiversityCountByTypeBo> bos,
                                            List<BiodiversityCountByTypeVo> list, Integer animalTotal, Integer botanyTotal) {
        BiodiversityCountByTypeVo typeVo = new BiodiversityCountByTypeVo();
        if (!CollectionUtils.isEmpty(bos)) {
            typeVo.setBiodiversityType(biodiversityType);
            Map<Integer, List<BiodiversityCountByTypeBo>> map = bos.stream().collect(Collectors.groupingBy(BiodiversityCountByTypeBo::getAnimalsPlantsType));
            for (Map.Entry<Integer, List<BiodiversityCountByTypeBo>> entry : map.entrySet()) {
                if (Constants.ZERO.equals(entry.getKey())) {
                    typeVo.setAnimalTotal(entry.getValue().size());
                    animalTotal = animalTotal + entry.getValue().size();
                    continue;
                }
                typeVo.setBotanyTotal(entry.getValue().size());
                botanyTotal = botanyTotal + entry.getValue().size();
            }
        }
        list.add(typeVo);
    }

    /**
     * @description: 实时抓怕数据统计
     * @param: []
     * @return: java.lang.Integer
     * @date: 2022/11/11 14:19
     * @version: 1.0
     **/
    @Override
    public Map<String, Object> getRealTimeFearCount() throws ClientException {
        //TODO
        //统计巡护上报和设备自动上报的数据
        long count = realtimeShootService.count();
        QueryWrapper<RealtimeShoot> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("get_time");
        wrapper.isNotNull("path").last("limit 1");
        RealtimeShoot realtimeShoot = realtimeShootService.getOne(wrapper);
        Map<String, Object> data = new HashMap<>();
        data.put("count", count);
        data.put("newest", realtimeShoot.getPath());
        return data;
    }

    /**
     * @param orgId
     * @description: 巡护里程数据统计
     * @param: []
     * @return: com.gk.panda.apis.entity.DataVisualization.vo.PatrolMileageCountVo
     * @date: 2022/11/11 14:19
     * @version: 1.0
     */
    @Override
    public PatrolMileageCountVo getPatrolMileageCount(String orgId) {
        PatrolMileageCountVo vo = new PatrolMileageCountVo();
        //获取机构IDs
        List<Integer> orgIds = getOrgIds(orgId);
        //查询近五年的数据统计
        List<DataCountByYear> bos = dataVisualizationMapper.getPatrolMileageCount(orgIds);
        List<DataCountByYear> patrols = new ArrayList<>();
        if (!CollectionUtils.isEmpty(bos)) {
            BigDecimal total = new BigDecimal(BigInteger.ZERO);
            //循环封装对应的数据
            for (DataCountByYear bo : bos) {
                BigDecimal num = new BigDecimal(bo.getTotalNum());
                num = num.divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP);
                bo.setTotalNum(num.toString());
                total = total.add(num);
            }
            vo.setTotalNum(total.toString());
            Map<Integer, List<DataCountByYear>> map = bos.stream().collect(Collectors.groupingBy(DataCountByYear::getYear));
            vo.setPatrolMap(map);
        }
        return vo;
    }

    /**
     * @param orgId
     * @description: 巡护事件数据统计
     * @param: []
     * @return: com.gk.panda.apis.entity.DataVisualization.vo.PatrolIncidentsCountVo
     * @date: 2022/11/11 14:19
     * @version: 1.0
     */
    @Override
    public PatrolIncidentsCountVo getPatrolIncidentsCount(String orgId) {
        PatrolIncidentsCountVo vo = new PatrolIncidentsCountVo();
        //TODO 表中没有机构ID
//        List<Integer> orgIds = getOrgIds(orgId);
        List<Integer> orgIds = null;
        //即时和普通的数据
        List<PatrolIncidentsCountBo> bos = dataVisualizationMapper.getPatrolIncidentsCount(orgIds);
        Integer total = Constants.ZERO;
        if (!CollectionUtils.isEmpty(bos)) {
            for (PatrolIncidentsCountBo bo : bos) {
                total = total + (bo.getNum() == null ? Constants.ZERO : bo.getNum());
                if (Constants.PLAIN.equals(bo.getType())) {
                    vo.setImmediate(bo.getNum());
                    continue;
                }
                vo.setOrdinary(bo.getNum());

            }
        }
        vo.setPatrolIncidentsTotalNum(total);
        return vo;
    }


    private List<Integer> getOrgIds(String orgId) {
        List<Integer> puisneOrgIds = null;
        if (StringUtils.isNotEmpty(orgId)) {
            puisneOrgIds = orgService.getPuisneOrgIds(Integer.valueOf(orgId));
        }
        return puisneOrgIds;
    }
}
